#ifndef XLCOMM_BASE_JSONHELPER_H_
#define XLCOMM_BASE_JSONHELPER_H_

#include <memory>

#include "json/json.h"
#include "xlcomm/base/logger.h"
#include "xlcomm/define.h"
#include "xlcomm/noncopyable.h"

namespace xlcomm {

class XLCOMM_API JsonHelper : noncopyable {
 public:
  static inline bool JsonstrToJson(const std::string& jsonstr,
                                   Json::Value& root) {
    const auto str_len = static_cast<int>(jsonstr.length());
    JSONCPP_STRING err;
    Json::CharReaderBuilder builder;
    const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
    if (!reader->parse(jsonstr.c_str(), jsonstr.c_str() + str_len, &root,
                       &err)) {
      LOG_ERROR << "Json::CharReader parse error! json str->" << jsonstr;
      return false;
    }
    return true;
  }

  static inline void JsonToJsonstr(const Json::Value& root,
                                   std::string& jsonstr) {
    jsonstr = root.toStyledString();
  }

  // 只能解析基本类型 int long bool float double string 的一组模板
  static bool JsonToType(const Json::Value& val, int& t) {
    if (!val.isIntegral()) return false;
    t = val.asInt();
    return true;
  }
  static bool JsonToType(const Json::Value& val, bool& t) {
    if (!val.isBool()) return false;
    t = val.asBool();
    return true;
  }
  static bool JsonToType(const Json::Value& val, double& t) {
    if (!val.isDouble()) return false;
    t = val.asDouble();
    return true;
  }
  static bool JsonToType(const Json::Value& val, std::string& t) {
    if (!val.isString()) return false;
    t = val.asCString();
    return true;
  }
};

}  // namespace xlcomm

#endif  // XLCOMM_BASE_JSONHELPER_H_